/*
 * Copyright 2010 Chad Retz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jdocng.shared.model;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlType;

import com.google.common.annotations.GwtCompatible;
import com.google.gson.annotations.Expose;
import com.sun.javadoc.PackageDoc;

/**
 * Implementation of {@link PackageDoc}
 *
 * @author Chad Retz
 */
@XmlType(name = "package")
@GwtCompatible(serializable = true)
@SuppressWarnings("serial")
public class PackageDocImpl extends DocImpl implements PackageDoc {
    
    //exposed fields
    
    @Expose
    private ClassDocImpl[] allClasses;
    
    @Expose
    private AnnotationDescImpl[] annotations;
    
    //PackageDoc interface impl
    
    @Override
    public ClassDocImpl[] allClasses() {
        return allClasses(true);
    }
    
    @Override
    public ClassDocImpl[] allClasses(boolean filter) {
        if (!filter) {
            return allClasses;
        }
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc.isIncluded()) {
                ret.add(doc);
            }
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    @Override
    public AnnotationDescImpl[] annotations() {
        return annotations;
    }
    
    @Override
    public AnnotationTypeDocImpl[] annotationTypes() {
        List<AnnotationTypeDocImpl> ret = new ArrayList<AnnotationTypeDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc instanceof AnnotationTypeDocImpl) {
                ret.add((AnnotationTypeDocImpl) doc);
            }
        }
        return ret.toArray(new AnnotationTypeDocImpl[0]);
    }
    
    @Override
    public ClassDocImpl[] enums() {
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc.isEnum()) {
                ret.add(doc);
            }
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    @Override
    public ClassDocImpl[] errors() {
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc.isError()) {
                ret.add(doc);
            }
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    @Override
    public ClassDocImpl[] exceptions() {
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc.isException()) {
                ret.add(doc);
            }
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    @Override
    public ClassDocImpl findClass(String className) {
        for (ClassDocImpl doc : allClasses) {
            if (className.equals(doc.name())) {
                return doc;
            }
        }
        return null;
    }
    
    @Override
    public ClassDocImpl[] interfaces() {
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc.isInterface()) {
                ret.add(doc);
            }
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    @Override
    public ClassDocImpl[] ordinaryClasses() {
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(allClasses.length);
        for (ClassDocImpl doc : allClasses) {
            if (doc.isOrdinaryClass()) {
                ret.add(doc);
            }
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    //other accessors
    
    public void setAllClasses(ClassDocImpl[] allClasses) {
        this.allClasses = allClasses;
    }
    
    public void setAnnotations(AnnotationDescImpl[] annotations) {
        this.annotations = annotations;
    }
}
